package com.abc.xxx.controller;

import com.abc.xxx.model.AccessibleView;
import com.abc.xxx.model.Role;
import com.abc.xxx.model.User;
import com.abc.xxx.model.vo.RoleDataScope;
import com.abc.xxx.service.RoleService;
import com.abc.xxx.service.UserService;
import com.abc.xxx.util.Result;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.abc.xxx.constants.DataScopes;
import com.abc.xxx.model.vo.PermissionAssignment;
import com.abc.xxx.service.AccessibleDeptService;
import com.abc.xxx.service.AccessibleViewService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

@Slf4j
@RestController
@RequestMapping("/roles")
public class RoleController {

    private static final String NO_AUTH = "权限不足：只有超级管理员才能";

    @Autowired
    private RoleService roleService;
    @Autowired
    private UserService userService;
    @Autowired
    private AccessibleViewService accessibleViewService;
    @Autowired
    private AccessibleDeptService accessibleDeptService;

    @GetMapping
    public Result findRoles(@AuthenticationPrincipal User user,
                            @RequestParam(value = "key", required = false) String key) {
        String oper = "查询角色列表";
        log.info("====>{}", oper);
        if (user.isNotRoot()) {
            return Result.error(oper).msg(NO_AUTH + oper);
        }
        QueryWrapper<Role> w = new QueryWrapper<>();
        if (isNotBlank(key)) {
            w.like("name", key);
        }
        return Result.success(oper).data("list", roleService.list(w));
    }

    @PostMapping
    public Result addRole(@AuthenticationPrincipal User user,
                          @RequestBody String body) {
        String oper = "新增角色";
        log.info("====>{}, body: {}", oper, body);
        if (user.isNotRoot()) {
            return Result.error(oper).msg(NO_AUTH + oper);
        }
        Role role = JSON.parseObject(body, Role.class);
        if (isBlank(role.getName())) {
            return Result.error(oper).msg("角色名称不能为空");
        }
        if (roleService.isRoleNameExists(role.getName())) {
            return Result.error(oper).msg("角色名称已存在");
        }
        if (role.getDataScope() == DataScopes.CUSTOM_DEPT_DATA) {
            if (role.getAccessibleDepts().isEmpty()) {
                return Result.error(oper).msg("自定义部门数据权限必须至少指定一个部门");
            }
        } else {
            role.getAccessibleDepts().clear();
        }
        role.setUpdated(LocalDateTime.now());
        roleService.saveRoleAndAccessibleDepts(role);
        return Result.success(oper).data("time", role.getUpdated());
    }

    @PatchMapping("/{roleId}")
    public Result updateRole(@AuthenticationPrincipal User user,
                             @PathVariable("roleId") Integer roleId,
                             @RequestBody String body) {
        String oper = "更新角色";
        log.info("====>{}, body: {}", oper, body);
        if (user.isNotRoot()) {
            return Result.error(oper).msg(NO_AUTH + oper);
        }

        Role role = JSON.parseObject(body, Role.class);
        role.setId(roleId);
        if (isBlank(role.getName())) {
            return Result.error(oper).msg("角色名称不能为空");
        }
        if (roleService.isRoleNameDuplicate(roleId, role.getName())) {
            return Result.error(oper).msg("新角色名称已存在");
        }
        if (role.getDataScope() == DataScopes.CUSTOM_DEPT_DATA) {
            if (role.getAccessibleDepts().isEmpty()) {
                return Result.error(oper).msg("自定义部门数据权限必须至少指定一个部门");
            }
        } else {
            role.getAccessibleDepts().clear();
        }
        roleService.updateRoleAndAccessibleDepts(role);
        return Result.success(oper);
    }

    @GetMapping("/{roleId}/custom-data-scope/depts")
    public Result findRoleCustomDataScopeDepts(@AuthenticationPrincipal User user,
                                               @PathVariable("roleId") Integer roleId) {
        String oper = "查询角色自定义数据权限关联的部门";
        log.info("====>{}", oper);
        if (user.isNotRoot()) {
            return Result.error(oper).msg(NO_AUTH + oper);
        }
        if (roleId == null) {
            return Result.error(oper).msg("角色id不能为空");
        }
        List<Integer> list = accessibleDeptService.findDeptIdsByRoleId(roleId);
        return Result.success(oper).list(list);
    }

    @DeleteMapping("/{roleId}")
    public Result deleteRole(@AuthenticationPrincipal User user,
                             @PathVariable("roleId") Integer roleId) {
        String oper = "删除角色";
        log.info("====>{}, roleId: {}", oper, roleId);
        if (user.isNotRoot()) {
            return Result.error(oper).msg(NO_AUTH + oper);
        }
        if (roleId == null) {
            return Result.error(oper).msg("角色id不能为空");
        }
        List<String> nicks = userService.findUserNickUsingTheRole(roleId);
        if (!nicks.isEmpty()) {
            return Result.error(oper).msg("无法删除角色，有用户正在使用该角色：" + String.join("，", nicks));
        }
        roleService.deleteRole(roleId);
        return Result.success(oper);
    }

    @PatchMapping("/{roleId}/assignment/pages-n-buttons")
    public Result assignPageAndButtonPermissions(@AuthenticationPrincipal User user,
                                                 @PathVariable Integer roleId,
                                                 @RequestBody String body) {
        String oper = "保存角色分配的功能权限";
        log.info("====>{}, roleId: {}, body: {}", oper, roleId, body);
        if (user.isNotRoot()) {
            return Result.error(oper).msg(NO_AUTH + oper);
        }
        List<AccessibleView> accessibleViews = JSON.parseArray(body, AccessibleView.class);
        accessibleViewService.assignPageAndButtonPermissions(roleId, accessibleViews);
        return Result.success(oper);
    }

    @PatchMapping("/{roleId}/assignment/data-scope")
    public Result assignDataScopePermissions(@AuthenticationPrincipal User user,
                                                 @PathVariable Integer roleId,
                                                 @RequestBody String body) {
        String oper = "保存角色分配的数据权限";
        log.info("====>{}, roleId: {}, body: {}", oper, roleId, body);
        if (user.isNotRoot()) {
            return Result.error(oper).msg(NO_AUTH + oper);
        }
        RoleDataScope roleDataScope = JSON.parseObject(body, RoleDataScope.class);
        roleService.assignDataScopePermissions(roleId, roleDataScope);
        return Result.success(oper);
    }

    @GetMapping("/{roleId}/assigned/pages-n-buttons")
    public Result findRoleAssignedPageAndButtonPermissions(@AuthenticationPrincipal User user,
                                                           @PathVariable Integer roleId) {
        String oper = "查询角色已分配的功能权限";
        log.info("====>{}, roleId: {}", oper, roleId);
        if (user.isNotRoot()) {
            return Result.error(oper).msg(NO_AUTH + oper);
        }
        List<String> list = accessibleViewService.findRoleAccessibleViews(roleId);
        return Result.success(oper).list(list);
    }

    @GetMapping("/{roleId}/assigned/data-scope")
    public Result findRoleAssignedDataScopePermissions(@AuthenticationPrincipal User user,
                                                           @PathVariable Integer roleId) {
        String oper = "查询角色已分配的数据权限";
        log.info("====>{}, roleId: {}", oper, roleId);
        if (user.isNotRoot()) {
            return Result.error(oper).msg(NO_AUTH + oper);
        }
        RoleDataScope ds = roleService.findRoleAccessibleDataScope(roleId);
        return Result.success(oper).obj(ds);
    }

    // --------------


//    @GetMapping("/{roleId}/permissions/tree")
//    public Result findRolePermissionsTree(@AuthenticationPrincipal User user,
//                                          @PathVariable("roleId") Integer roleId) {
//        String oper = "查询角色已分配的权限";
//        log.info("====>{}", oper);
//        if (user.isNotRoot()) {
//            return Result.error(oper).msg(NO_AUTH + oper);
//        }
//        List<View> permissions = accessibleViewService.findRoleAccessibleViews(roleId);
//        List<AccessiblePage> accessiblePages = accessibleViewService.convertToPageButtonTree(permissions);
//        return Result.success(oper).data("authorizedPages", accessiblePages);
//    }

    @PatchMapping("/assignment/pages/{pageCode}/buttons")
    public Result assignButtonPermissions(@AuthenticationPrincipal User user,
                                          @PathVariable("pageCode") String pageCode,
                                          @RequestBody PermissionAssignment form) {
        String oper = "保存角色分配的按钮权限";
        log.info("====>{}, body: {}", oper, JSON.toJSONString(form));
        if (user.root()) {
            form.setPage(pageCode);
            return accessibleViewService.assignButtonPermissions(oper, form);
        }
        return Result.error(oper).msg("权限不足：只有是超级管理员才能保存角色分配的按钮权限");
    }


}
